from typing import List

from flask import Blueprint, request, current_app

from app.controllers.response.response import SuccessResult
from app.database import convert
from app.models.po.gaolu.gaolu_diagnose_rule import GaoLuDiagnoseRulePO
from app.models.po.gaolu.gaolu_diagnose_data import GaoLuDiagnoseScorePO, GaoLuDiagnoseCountPO
from app.utils import string_util, date_util, simple_util
from app.utils.sys_utils import GaoLuEncoder
from datetime import datetime
from sqlalchemy import func
import math
import json
from collections import OrderedDict
import logging as log

bp = Blueprint('gaolu_diagnose', __name__, url_prefix="/api/v1/gaolu/diagnose")
gaolu_diagnose_bp = bp


@gaolu_diagnose_bp.route('/rules', methods=['GET'])
def rule_list():
    results: List[GaoLuDiagnoseRulePO] = convert.query(GaoLuDiagnoseRulePO, is_deleted=0).all()
    for result in results:
        if result.lower == -999999:
            result.lower = None
        if result.upper == 999999:
            result.upper = None
        result.__dict__.update(json.loads(result.section))

    return SuccessResult(detail=results, encoder=GaoLuEncoder)


@gaolu_diagnose_bp.route('/score', methods=['GET'])
def variable_score():
    date = request.args.get('date')

    if string_util.is_empty(date):
        date = date_util.get_start_of_day(datetime.now())

    results: List[GaoLuDiagnoseRulePO] = convert.query(GaoLuDiagnoseRulePO, is_deleted=0).all()
    score: GaoLuDiagnoseScorePO = convert.query(GaoLuDiagnoseScorePO, date_time=date).first()

    if score is None:
        return SuccessResult(detail=dict(group=[],
                                         ind=[]), encoder=GaoLuEncoder)

    score_dict = score.__dict__

    def getZero(v):
        if v is None: return 0
        return v

    group_items = {}
    rule_items = {}
    for result in results:
        group_item = group_items.get(result.scope,
                                     dict(totalScore=0, loseScore=0, loseRate=0,score=0,
                                          name=result.scope_name,key=result.scope))
        group_item['totalScore'] = group_item['totalScore'] + result.score

        rule_item = rule_items.get(result.name, dict(loseScore=0, loseRate=0, name=result.desc))
        rule_item['score'] = score_dict.get(result.name)
        rule_item['loseScore'] = round(result.score-getZero(score_dict.get(result.name)),2)
        rule_item['loseRate'] = str(round(rule_item['loseScore'] / result.score * 100, 2))+"%"
        rule_items[result.name] = rule_item

        group_item['score'] = round(group_item['score'] + getZero(rule_item['score']),2)
        group_item['loseScore'] = round(group_item['loseScore'] + getZero(rule_item['loseScore']),2)
        group_item['loseRate'] = str(round(abs(group_item['loseScore']) / group_item['totalScore']*100, 2))+"%"
        group_items[result.scope] = group_item

    sum = 0
    lose_sum = 0
    for key,item in group_items.items():
        sum = sum + item['totalScore']
        lose_sum = lose_sum + item['loseScore']

    group_items['total'] = dict(totalScore=round(sum,2), loseScore=round(lose_sum,2),
                                loseRate=str(round(abs(lose_sum) / sum * 100, 2))+"%",name="总分",key="total")

    return SuccessResult(detail=dict(group=list(group_items.values()),
                                     ind=list(rule_items.values())), encoder=GaoLuEncoder)


@gaolu_diagnose_bp.route('/count', methods=['GET'])
def shifting_count():
    date = request.args.get('date')

    if date is None:
        date = date_util.get_start_of_day(datetime.now())

    condition = []
    condition.append(func.count(GaoLuDiagnoseCountPO.id).label('count'))
    for x in GaoLuDiagnoseCountPO.__table__.columns:
        if x.name not in ['id', 'date_time', 'rule_id']:
            condition.append(func.sum(x).label(x.name))
    result_set = convert.query(GaoLuDiagnoseCountPO,
                               GaoLuDiagnoseCountPO.date_time == date) \
        .with_entities(*condition).first()

    result = result_set._asdict()
    if result['count'] == 0:
        return SuccessResult(detail={}, encoder=GaoLuEncoder)

    result = {k:v for k,v in result.items() if v is not None}
    result = simple_util.sort_value(result,False)

    del result["count"]

    return SuccessResult(detail=result, encoder=GaoLuEncoder)
